#pragma once

#include "helper/resource/IOpenable.h"

// only open once
namespace helper {
namespace resource {

// concept : 
//	R() : false ;
//	operator bool(R) = true -> ok; false -> failed 
template<typename R>
class Openable : public IOpenable<R>{
public:
	~Openable() override {}

	typedef R return_type;

	return_type open() override {
		if(!isOpened()){
			auto && ret = _open();
			if(ret){
				_opened = true;
			}
			return ret;
		}
		return return_type();
	}

	return_type close() override {
		if(isOpened()){
			auto && ret = _close();
			if(ret){
					_opened = false;
			}
			return ret;
		}
		return return_type();
	}

	bool isOpened() const override {
		return _opened;
	}

protected:
	virtual return_type _open() = 0;
	virtual return_type _close() = 0;
private:
	bool _opened = false;
};

}//namespace resource
}//namespace helper

#include "helper/resource/ErrorCodeOpenable.h"
